package com.geovis.boot.common.util;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.interactive.action.PDAction;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionURI;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink;
import org.apache.pdfbox.text.PDFTextStripper;
/**
 * @Author 月
 * @Description //TODO $
 * @Date 17:30
 * @Param
 * @return
 * @Version 1.0
 */
public class PdfUtils {

    /**
     * 替换pdf中的连接的url跳转地址，但是显示的不会变，只是修改点击跳转的地址
     *
     * @throws InvalidPasswordException
     * @throws IOException
     */
    public static void ReplaceURLs(String pdfPath, String url) throws InvalidPasswordException, IOException {
        PDDocument doc = null;
        try {
            doc = PDDocument.load(new File(pdfPath));
            int pageNum = 0;
            for (PDPage page : doc.getPages()) {
                pageNum++;
                List<PDAnnotation> annotations = page.getAnnotations();

                for (PDAnnotation annotation : annotations) {
                    PDAnnotation annot = annotation;
                    if (annot instanceof PDAnnotationLink) {
                        PDAnnotationLink link = (PDAnnotationLink) annot;
                        PDAction action = link.getAction();
                        if (action instanceof PDActionURI) {
                            PDActionURI uri = (PDActionURI) action;
                            String oldURI = uri.getURI();
                            String newURI = url;
                            uri.setURI(newURI);
                        }
                    }
                }
                doc.save(pdfPath);
            }
        } finally {
            if (doc != null) {
                doc.close();
            }
        }
    }

    /**
     * 删除PDF里面的指定页
     *
     * @throws IOException
     * @throws InvalidPasswordException
     */
    public static void removePdfPage(String pdfPath, Integer pageNum) throws IOException, InvalidPasswordException {
        try (PDDocument document = PDDocument.load(new File(pdfPath))) {
            if (document.isEncrypted()) {
                throw new IOException("Encrypted documents are not supported for this example");
            }
            if (document.getNumberOfPages() <= 1) {
                throw new IOException(
                        "Error: A PDF document must have at least one page, " + "cannot remove the last page!");
            }
            document.removePage(pageNum - 1);// 删除第2页
            document.save(pdfPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * PDF中增加图片
     *
     * @throws IOException
     * @throws InvalidPasswordException
     */
    public static void addImg2PDF(String imgPath, String pdfPath) throws IOException, InvalidPasswordException {
        try (PDDocument doc = PDDocument.load(new File(pdfPath))) {
            PDPage page = doc.getPage(0);
            PDImageXObject pdImage = PDImageXObject.createFromFile(imgPath, doc);

            try (PDPageContentStream contentStream = new PDPageContentStream(doc, page, AppendMode.APPEND, true,
                    true)) {
                // contentStream.drawImage(ximage, 20, 20 );
                // better method inspired by
                // http://stackoverflow.com/a/22318681/535646
                // reduce this value if the image is too large
                float scale = 1f;
                contentStream.drawImage(pdImage, 20, 20, pdImage.getWidth() * scale, pdImage.getHeight() * scale);
            }
            doc.save(pdfPath);
        }
    }

    /**
     * 阅读PDF文件的内容，支持阅读中文(如果需要阅读指定页面的PDF自己改写此方法)
     *
     * @throws IOException
     * @throws InvalidPasswordException
     */
    public static void readPDFText(String pdfPath) throws IOException, InvalidPasswordException {
        try (PDDocument document = PDDocument.load(new File(pdfPath))) {
            AccessPermission ap = document.getCurrentAccessPermission();
            if (!ap.canExtractContent()) {
                throw new IOException("You do not have permission to extract text");
            }
            PDFTextStripper stripper = new PDFTextStripper();
            stripper.setSortByPosition(true);
            for (int p = 1; p <= document.getNumberOfPages(); ++p) {
                stripper.setStartPage(p);
                stripper.setEndPage(p);
                String text = stripper.getText(document);
            }
        }
    }

    /**
     * 创建空的PDF文件并且添加一个空白页，多页可以插入多个PDPage
     *
     * @throws IOException
     */
    public static void createBlankPDF(String pdfPath) throws IOException {
        String filename = pdfPath;
        try (PDDocument doc = new PDDocument()) {
            // a valid PDF document requires at least one page
            PDPage blankPage = new PDPage();
            doc.addPage(blankPage);
            doc.save(filename);
        }
    }

    /**
     * 图片转换为PDF文件
     *
     * @throws IOException
     */
    public static void img2PDF(String imgPath, String pdfPathOrg) throws IOException {
        String imagePath = imgPath;
        String pdfPath = pdfPathOrg;
        try (PDDocument doc = new PDDocument()) {
            PDPage page = new PDPage();
            doc.addPage(page);
            PDImageXObject pdImage = PDImageXObject.createFromFile(imagePath, doc);
            try (PDPageContentStream contents = new PDPageContentStream(doc, page)) {
                contents.drawImage(pdImage, 20, 20);
            }
            doc.save(pdfPath);
        }
    }

    /**
     * 创建PDF文件并写入内容(暂时不支持写入中文)
     *
     * @throws IOException
     */
    public static void createPDF(String pdfPath) throws IOException {
        String filename = pdfPath;
        String message = "pdf";// 字体不能有中文，暂时不支持中文
        try (PDDocument doc = new PDDocument()) {
            PDPage page = new PDPage();
            doc.addPage(page);
            PDFont font = PDType1Font.HELVETICA_BOLD;
            try (PDPageContentStream contents = new PDPageContentStream(doc, page)) {
                contents.beginText();
                contents.setFont(font, 12);
                contents.newLineAtOffset(100, 700);
                contents.showText(message);
                contents.endText();
            }
            doc.save(filename);
        }
    }
}
